<template>
  <n-cascader
    v-bind="props"
    :options="options"
    style="min-width: 194px"
    @load="handleChildrenLoad"
    @update:value="handleChange"
  />
</template>

<script lang="ts">
  import { getProvinces, getPrefectures, getCounties } from 'china-region'
  import { defineComponent, reactive, toRefs } from 'vue'
  import { NCascader, CascaderOption } from 'naive-ui'

  export default defineComponent({
    name: 'XChinaRegion',
    components: {
      NCascader
    },
    props: {
      ...NCascader.props,
      clearable: {
        type: Boolean,
        default: true
      },
      remote: {
        type: Boolean,
        default: true
      },
      checkStrategy: {
        type: String,
        default: 'child'
      },
      valueField: {
        type: String,
        default: 'name'
      },
      placeholder: {
        type: String,
        default: '请选择省市区'
      }
    },
    emits: ['confirm'],
    setup($props, { emit: $emit }) {
      const $state = reactive({
        props: toRefs($props) || {},
        options: [],
        all: []
      })

      // 加载数据
      const getChildrenList = (type: string, code: null | string) => {
        let list
        // 省
        if (type === 'province') {
          list = getProvinces()
            // .filter((item) => !/台湾|香港|澳门/.test(item.name))
            .map((item) => {
              return {
                ...item,
                label: item.name,
                value: item.code,
                childrenType: 'city',
                isLeaf: false
              }
            })
          $state.options = list
        }
        // 市
        if (type === 'city') {
          let isLeaf = false
          list = getPrefectures(code)
          if (!list.length) {
            list = getCounties(code)
            isLeaf = true
          }
          list = list.map((item) => {
            return {
              ...item,
              label: item.name,
              value: item[$props.valueField],
              childrenType: 'area',
              parentId: code,
              isLeaf
            }
          })
        }
        // 区
        if (type === 'area') {
          list = getCounties(code).map((item) => {
            return {
              ...item,
              label: item.name,
              value: item[$props.valueField],
              parentId: code,
              isLeaf: true
            }
          })
        }
        return list
      }
      // 加载一级
      getChildrenList('province', null)

      // 加载下一级
      const handleChildrenLoad = (option: { code: string; children: any; childrenType: string }) => {
        return new Promise<void>(async (resolve) => {
          option.children = getChildrenList(option.childrenType, option.code)
          resolve()
        })
      }

      // 数据选择
      const handleChange = (
        value: string | number | Array<string | number> | null,
        option: CascaderOption,
        pathValues: Array<CascaderOption | null> | Array<CascaderOption[] | null> | null
      ) => {
        // 给直辖市增加为三级数据
        if (pathValues?.length === 2) {
          pathValues.unshift(pathValues[0])
        }
        $emit('confirm', value, option, pathValues)
      }

      // 数据回填
      // 直辖市数据去重
      const defaultValue = Array.from(new Set($props.defaultValue || []))
      if (defaultValue.length) {
        for (let index = 0; index < defaultValue.length - 1; index++) {
          let option = $state.options.find((item) => item.name === defaultValue[0])
          // 二级数据获取，暂时写死
          if (index === 1) {
            option = option.children.find((item) => item.name === defaultValue[1])
          }
          handleChildrenLoad(option)
        }
      }

      return {
        ...toRefs($state),
        handleChildrenLoad,
        handleChange
      }
    }
  })
</script>

<style lang="scss" scoped>
  .n-form--inline {
    &.is-wrap {
      flex-wrap: wrap;
    }
  }
</style>
